using System;
using System.Security.Principal;
using Sok.Munkae.Core;
using Sok.Munkae.Core.DataInterfaces;

namespace Sok.Munkae.ApplicationServices
{
    public interface IMembershipService
    {
        UserValidationResult ValidateUser(string userName, string password);
        User RetrieveUser(string userName);
    }

    public class MembershipService : IMembershipService
    {
        private IUserRepository userRepository;
        
        // you'd probably also need some sort of Encryption provider here in a real-world app, to deal with comparing the encrypted value coming in from the repository to the unencrypted value coming in to this service.
        public MembershipService(IUserRepository userRepository) 
        {
            this.userRepository = userRepository;
        }

        public UserValidationResult ValidateUser(string userName, string password)
        {
            User user = userRepository.GetByUserName(userName);
            if(null==user)
            {
                return new UserValidationResult().InvalidUserName();
            }
            
            //normally you'd be dealing with some sort of password encryption coming in from the database here...but eh....DEMO!
            if(user.Password != password)
            {
                return new UserValidationResult().InvalidPassword();
            }

            return new UserValidationResult().Success(user.Init());
        }

        public User RetrieveUser(string userName)
        {
            return userRepository.GetByUserName(userName);
        }
    }

    public enum UserValidationResultType
    {
        Success,
        InvalidUserName,
        InvalidPassword,
        AccountLocked,
        AccountDisabled
    }

    public enum UserValidationResultDisposition
    {
        Success,
        Failure
    }

    public class UserValidationResult
    {
        public User User { get; set; }
        public UserValidationResultType ResultType { get; set; }
        public UserValidationResultDisposition ResultDisposition { get; set; }

        public UserValidationResult InvalidUserName()
        {
            ResultDisposition = UserValidationResultDisposition.Failure;
            ResultType = UserValidationResultType.InvalidUserName;
            User = null;
            return this;
        }

        public UserValidationResult InvalidPassword()
        {
            ResultDisposition = UserValidationResultDisposition.Failure;
            ResultType = UserValidationResultType.InvalidPassword;
            User = null;
            return this;
        }
        
        public UserValidationResult Success(User user)
        {
            ResultDisposition = UserValidationResultDisposition.Success;
            ResultType = UserValidationResultType.Success;
            User = user;
            return this;
        }
    }
}